package com.meepo.framework.design.list

import android.annotation.SuppressLint
import android.content.Context
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.ColorRes
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
import com.meepo.framework.R
import java.lang.Exception

@Suppress("UNCHECKED_CAST")
@SuppressLint("SetTextI18n")
open class ViewHolder(val mContext: Context, itemView: View) : RecyclerView.ViewHolder(itemView) {

    private var mView: SparseArray<View> = SparseArray()

    fun <T : View> getView(viewId: Int): T? {

        try {
            var view: View? = mView.get(viewId)
            if (view == null) {
                view = itemView.findViewById(viewId)
            }

            view?.let {
                mView.put(viewId, view)
                return view as T
            }

            return null

        } catch (e: Exception) {
            e.printStackTrace()
        }

        return null
    }


    fun <T : ViewGroup> getViewGroup(viewId: Int): T? {
        try {
            return getView<ViewGroup>(viewId) as T
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return null
    }

    fun setText(viewId: Int, text: CharSequence?, colorId: Int = 0): ViewHolder {
        val view = getView<TextView>(viewId)
        view?.text = "" + text

//        this.setTextColor(viewId, colorId)

        return this
    }

    fun setTextColor(viewId: Int, @ColorRes colorId: Int) : ViewHolder{
        getView<TextView>(viewId)?.setTextColor(mContext.resources.getColor(colorId))
        return this
    }

    fun setHintText(viewId: Int, text: CharSequence?): ViewHolder {
        val view = getView<TextView>(viewId)
        view?.hint = "" + text
        return this
    }

    fun setImageResource(viewId: Int, resId: Int): ViewHolder {
        val iv = getView<ImageView>(viewId)
        iv?.setImageResource(resId)
        return this
    }

    fun setImagePath(viewId: Int, path: String?, imageLoader: ImageLoader): ViewHolder {
        getView<ImageView>(viewId)?.let {
            imageLoader.loadImage(it, path ?: "")
        }

        return this
    }

    fun setImagePath(viewId: Int, path: String?): ViewHolder {
        return setImagePath(viewId, path, defaultImageLoader)
    }

    fun setImagePath(iv: ImageView, path: String?): ViewHolder {
        setImagePath(iv, path, defaultImageLoader)
        return this
    }

    fun setImagePath(iv: ImageView, path: String?, imageLoader: ImageLoader): ViewHolder {
        imageLoader.loadImage(iv, path ?: "")
        return this
    }

    fun setOnClickListener(viewId: Int, listener: View.OnClickListener): ViewHolder {
        getView<View>(viewId)?.setOnClickListener(listener)
        return this
    }

    fun setVisibility(viewId: Int, visibility: Int): ViewHolder {
        getView<View>(viewId)?.visibility = visibility
        return this
    }

    fun setOnItemClickListener(listener: View.OnClickListener): ViewHolder {
        itemView.setOnClickListener(listener)
        return this
    }

    fun setOnItemLongClickListener(listener: View.OnLongClickListener): ViewHolder {
        itemView.setOnLongClickListener(listener)
        return this
    }

    interface ImageLoader {
        fun loadImage(iv: ImageView, path: String)
    }


    private val defaultImageLoader = object : ImageLoader {
        override fun loadImage(iv: ImageView, path: String) {
            Glide.with(mContext).load(path).apply(
                RequestOptions().centerCrop().diskCacheStrategy(DiskCacheStrategy.ALL)
            ).transition(DrawableTransitionOptions().crossFade(0))
                .into(iv)
        }

    }

}